<template>
  <div id="pictureDetailPage">
    <a-spin :spinning="loading" tip="Loading...">
      <!-- 如果详情加载失败,展示异常信息 -->
      <a-row :gutter="[16, 16]" v-if="!loading && picture">
        <!-- 图片展示区 -->
        <a-col :sm="24" :md="16" :xl="18">
          <a-card title="图片预览">
            <!-- 为了防止图片过高,给图片设置最大高度,并设置object-fit: contain"让图片自适应-->
            <a-image
              style="max-height: 600px; object-fit: contain"
              :src="picture.host + picture.url"
              alt="图片预览"
            />
          </a-card>
        </a-col>
        <!-- 图片信息区 -->
        <a-col :sm="24" :md="8" :xl="6">
          <a-card title="图片信息">
            <a-descriptions :column="1">
              <a-descriptions-item label="作者">
                <a-space>
                  <a-avatar :size="24" :src="picture.user?.authorAvatar" />
                  <div>{{ picture.user.userName }}</div>
                </a-space>
              </a-descriptions-item>
              <a-descriptions-item label="名称">
                {{ picture.name ?? '未命名' }}
              </a-descriptions-item>
              <a-descriptions-item label="简介">
                {{ picture.introduction ?? '-' }}
              </a-descriptions-item>
              <a-descriptions-item label="分类">
                {{ picture.category ?? '默认' }}
              </a-descriptions-item>
              <a-descriptions-item label="标签">
                <a-tag v-for="tag in picture.tags" :key="tag">
                  {{ tag }}
                </a-tag>
              </a-descriptions-item>
              <a-descriptions-item label="格式">
                {{ picture.picFormat ?? '-' }}
              </a-descriptions-item>
              <a-descriptions-item label="宽度">
                {{ picture.picWidth ?? '-' }}
              </a-descriptions-item>
              <a-descriptions-item label="高度">
                {{ picture.picHeight ?? '-' }}
              </a-descriptions-item>
              <a-descriptions-item label="宽高比">
                {{ picture.picScale ?? '-' }}
              </a-descriptions-item>
              <a-descriptions-item label="大小">
                {{ formatSize(picture.picSize) }}
              </a-descriptions-item>
              <a-descriptions-item label="主色调">
                <a-space>
                  {{ picture.picColor ?? '-' }}
                  <div
                    v-if="picture.picColor"
                    :style="{
                      backgroundColor: toHexColor(picture.picColor),
                      width: '16px',
                      height: '16px',
                    }"
                  ></div>
                </a-space>
              </a-descriptions-item>
            </a-descriptions>
            <a-space wrap>
              <a-button type="default" :icon="h(RollbackOutlined)" @click="() => $router.push('/')">
                返回
              </a-button>
              <!--图片下载 为了方便实现,直接根据对象存储的URL下载图片,不经过后端
              使用file-saver库,下载指定URL或者后端返回blob(二进制)内容为文件
              npm install file-saver
              npm i --save-dev @types/file-saver
              -->
              <a-button type="default" @click="doDownload">
                下载
                <template #icon>
                  <ArrowDownOutlined />
                </template>
              </a-button>
              <a-button type="primary" ghost @click="doShare">
                分享
                <template #icon>
                  <share-alt-outlined />
                </template>
              </a-button>
              <a-button v-if="canEditPicture" type="default" @click="doEdit">
                编辑
                <template #icon>
                  <EditOutlined />
                </template>
              </a-button>
              <a-button v-if="canDeletePicture" type="default" danger @click="doDelete">
                删除
                <template #icon>
                  <DeleteOutlined />
                </template>
              </a-button>
            </a-space>
          </a-card>
        </a-col>
      </a-row>
      <div v-else-if="error">{{ error }}</div>
    </a-spin>

    <ShareModal :open="open" :link="shareLink" title="分享" @update:open="handleModalOpen" />
  </div>
</template>

<script setup lang="ts">
import { computed, h, onMounted, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { deletePictureUsingPost, getPictureVoByIdUsingGet } from '@/api/pictureController'
import { downloadImage, formatSize } from '@/utils/index.ts'
import {
  ArrowDownOutlined,
  DeleteOutlined,
  EditOutlined,
  RollbackOutlined,
  ShareAltOutlined,
} from '@ant-design/icons-vue'
import { message } from 'ant-design-vue'
import { useLoginUserStore } from '@/stores/useLoginUserStore.ts'
import ACCESS_ENUM from '@/router/AccessEnum.ts'
import ShareModal from '@/components/ShareModal.vue'
import { SPACE_PERMISSION_ENUM } from '@/constants/space.ts'

const route = useRoute()
const loading = ref(true)
const error = ref<string | null>(null)
const picture = ref<API.PictureVO>({})
const props = defineProps<{
  id: string | number
}>()

/**
 * 初始化加载图片信息
 */
onMounted(async () => {
  try {
    const response = await getPictureVoByIdUsingGet({ id: props.id })
    if (response.code === 0 && response.data) {
      picture.value = response.data
    } else {
      throw new Error(response.message || '无法加载图片')
    }
  } catch (err) {
    error.value = err.message
  } finally {
    loading.value = false
  }
})

const loginUserStore = useLoginUserStore()

// 判断是否可以编辑 使用 computed 创建计算属性
const canEdit = computed(() => {
  const loginUser = loginUserStore.loginUser
  // 如果未登录不可以编辑，则返回false
  if (!loginUserStore.isLogin) {
    return false
  }
  // 仅作者或者管理员可以编辑
  const user = picture.value?.user || {}
  return loginUser.id === user.id || loginUser.userRole === ACCESS_ENUM.ADMIN
})

const router = useRouter()

// 通用权限检查函数
function createPermissionChecker(permission: string) {
  return computed(() => {
    return (picture.value.permissionList ?? []).includes(permission)
  })
}

// 定义权限检查
const canManageSpaceUser = createPermissionChecker(SPACE_PERMISSION_ENUM.SPACE_USER_MANAGE) // 管理空间用户权限
const canUploadPicture = createPermissionChecker(SPACE_PERMISSION_ENUM.PICTURE_UPLOAD) // 上传图片权限
const canEditPicture = createPermissionChecker(SPACE_PERMISSION_ENUM.PICTURE_EDIT) // 编辑图片权限
const canDeletePicture = createPermissionChecker(SPACE_PERMISSION_ENUM.PICTURE_DELETE) // 删除图片权限

// 不在使用下面的校验,而是上面的校验
// 编辑图片
// 编辑
const doEdit = () => {
  console.log(picture.value)
  router.push({
    path: '/add_picture',
    query: {
      id: picture.value.id,
      spaceId: picture.value.spaceId,
    },
  })
}

// 删除图片
const doDelete = async () => {
  const id = picture.value.id
  if (!id) {
    return
  }
  const res = await deletePictureUsingPost({ id })
  if (res.code === 0) {
    message.success('删除成功')
    await router.push({
      path: '/',
      replace: true,
    })
  } else {
    message.error('删除失败')
  }
}

// 下载图片
const doDownload = async () => {
  downloadImage(picture.value.url)
}

const toHexColor = (input: string) => {
  // 检查输入是否为字符串
  if (typeof input !== 'string') {
    throw new Error('输入必须为字符串')
  }

  // 去掉可能存在的 '0x' 或 '#' 前缀
  let colorValue = input.replace(/^#|0x/, '')

  // 确保颜色值是6位十六进制数
  if (!/^[0-9A-Fa-f]{6}$/.test(colorValue)) {
    throw new Error('无效的十六进制颜色代码。它应该是一个6位十六进制数')
  }

  // 返回标准 #RRGGBB 格式的颜色代码
  return `#${colorValue.toUpperCase()}`
}

// 模态框是否可见
const open = ref(false)
// 模态框控制事件
const handleModalOpen = (value: boolean) => {
  open.value = value
}

// 分享弹窗引用
const shareModalRef = ref()
// 分享链接
const shareLink = ref<string>()
// 分享
const doShare = (picture: API.PictureVO, e: Event) => {
  shareLink.value = `${window.location.protocol}//${window.location.host}/picture/${picture.id}`
  open.value = true
}
</script>

<style scoped>
/* Your styles here */
</style>
